package com.umeox.watch.moto.chat.ui

import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.RemoteException
import android.telephony.TelephonyManager
import android.text.TextUtils
import android.view.View
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.Toast
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.umeox.moto.common.log.Logger
import com.umeox.moto.common.utils.FileUtils
import com.umeox.moto.watch.themes.app.ThemeAppCompatActivity
import com.umeox.moto.watch.themes.util.UToast
import com.umeox.moto.watch.themes.widget.TextView
import com.umeox.watch.moto.chat.BuildConfig
import com.umeox.watch.moto.chat.R
import com.umeox.watch.moto.chat.adapter.WatchMessageMultiItemAdapter
import com.umeox.watch.moto.chat.db.*
import com.umeox.watch.moto.chat.event.ContactRefreshEvent
import com.umeox.watch.moto.chat.proto.ChatMsgProtos
import com.umeox.watch.moto.chat.utils.Constants
import com.umeox.watch.moto.chat.utils.Utility
import com.umeox.watch.moto.chat.widget.AlarmRecorderDialog
import com.umeox.watch.moto.chat.widget.AlarmRecorderDialog.OnDialogActionListener
import com.umeox.watch.moto.chat.widget.ChatRecorderDialog
import com.umeox.watch.moto.dataservice.DataProvider
import com.umeox.watch.moto.dataservice.interfaces.IChat
import com.umeox.watch.moto.dataservice.proxy.ChatProxy
import com.umeox.watch.moto.dataservice.proxy.PushApiClientProxy
import kotlinx.coroutines.launch
import me.everything.android.ui.overscroll.OverScrollDecoratorHelper
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode


/**
 * Created by Rambo 2021/8/23
 * Describe:
 */
class WatchMessageActivity : ThemeAppCompatActivity(), MessageDelegate.MessageHandlerListener,
    View.OnClickListener {

    companion object {
        private val TAG = WatchMessageActivity::class.java.simpleName
        private const val EXTRA_ACTION_CHAT_ID = "extra_action_chat_id"
        const val EXTRA_PHRASE = "phrase"
        private const val REQUEST_CODE_EMOJI = 1000
        private const val REQUEST_CODE_TAKE_PHOTO = 2000
        private const val REQUEST_CODE_SHARE_PHOTO = 3000
        private const val REQUEST_CODE_PHRASE = 4000
        private const val REQUEST_CODE = 666
    }


    private lateinit var rvMsg: RecyclerView
    private lateinit var tvTitle: TextView
    private lateinit var ivEdit: ImageView
    private lateinit var rlTitle: RelativeLayout
    private val mHandler: Handler = Handler()
    private val ACTION_CLEAR_NOTIFY_CHAT = "com.wherecom.intent.action.CLEAR_NOTIFY_CHAT"
    private var mAdapter: WatchMessageMultiItemAdapter? = null

    private lateinit var chatBinder: IChat

    private var mContact: ContactInfo? = null

    private lateinit var mLayoutManager: LinearLayoutManager

    private var sharePicPaths: ArrayList<String>? = null

    private var isCallReceiverRegistered: Boolean = false

    private var mCallReceiver: BroadcastReceiver = object : BroadcastReceiver() {
        //如果有电话或者视频电话进来，停止正在播放的语聊
        override fun onReceive(context: Context, intent: Intent) {
            val action = intent.action
            if (Constants.ACTION_INCOMING_CALL.equals(action, true)) {
                val telephony = context.getSystemService(TELEPHONY_SERVICE) as TelephonyManager
                when (telephony.callState) {
                    TelephonyManager.CALL_STATE_RINGING -> stopPlay()
                }
            } else if (Constants.ACTION_RINGING_VIDEO_CALL.equals(action, true)) {
                stopPlay()
            }
        }
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.act_msg_list)
        mContact = getContact()
        if (mContact == null) {
            finish()
            return
        }
        initView()

        EventBus.getDefault().register(this)
    }

    override fun onStart() {
        super.onStart()
        val intent = Intent()
        intent.action = ACTION_CLEAR_NOTIFY_CHAT
        intent.putExtra(EXTRA_ACTION_CHAT_ID, mContact!!.friendId)
        intent.putExtra(ACTION_CLEAR_NOTIFY_CHAT, true)
        sendBroadcast(intent)
    }

    override fun onPostCreate(savedInstanceState: Bundle?) {
        super.onPostCreate(savedInstanceState)
        MessageDelegate.getManager().registerMessageListener(this, mContact)
        registerReceiver()

        mAdapter = WatchMessageMultiItemAdapter(this, mContact!!)
        mAdapter?.setData(getMessages())
        rvMsg.adapter = mAdapter
        mLayoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
        mLayoutManager.stackFromEnd = false
        rvMsg.layoutManager = mLayoutManager
        // Vertical
        OverScrollDecoratorHelper.setUpOverScroll(
            rvMsg,
            OverScrollDecoratorHelper.ORIENTATION_VERTICAL
        )
        if (mAdapter?.itemCount!! > 0) {
            mLayoutManager.scrollToPosition(mAdapter?.itemCount!! - 1)
        }

    }

    private fun registerReceiver() {
        val intentFilter = IntentFilter()
        intentFilter.addAction(Constants.ACTION_INCOMING_CALL)
        intentFilter.addAction(Constants.ACTION_RINGING_VIDEO_CALL)
        registerReceiver(mCallReceiver, intentFilter)
        isCallReceiverRegistered = true
    }


    override fun onStop() {
        super.onStop()
        val intent = Intent()
        intent.action = ACTION_CLEAR_NOTIFY_CHAT
        intent.putExtra(ACTION_CLEAR_NOTIFY_CHAT, false)
        sendBroadcast(intent)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        setIntent(intent)
        mContact = getContact()
        if (mContact == null) {
            finish()
        }
    }

    private fun getContact(): ContactInfo? {
        var temp: ContactInfo? = null
        val data = intent.data
        if (data != null) {
            val uid: String? = data.getQueryParameter("uid")
            temp = AppDatabase.get().contactInfoDao().queryByFriendId(uid!!)
        }
        return temp ?: intent.getParcelableExtra(Constants.EXTRA_CONTACT)
    }

    override fun onPause() {
        stopPlay()
        super.onPause()
    }


    @SuppressLint("ClickableViewAccessibility")
    private fun initView() {

        rvMsg = findViewById(R.id.lvMsg)
        tvTitle = findViewById(R.id.tvTitle)
        rlTitle = findViewById(R.id.rlTitle)
        ivEdit = findViewById(R.id.ivEdit)
        tvTitle.text = mContact?.name ?: ""
        val view = findViewById<View>(R.id.iv_reply)
        view.setOnClickListener(this)
        findViewById<ImageView>(R.id.iv_voice).setOnClickListener(this)

        chatBinder = ChatProxy.fetchBinder()

        ivEdit.setOnClickListener {
            GroupNameEditActivity.intoGroupNameEditActivity(this, mContact!!)
        }

        //判断是管理员  并且 是家庭群组  才显示
        if (mContact!!.isAdmin && mContact!!.isGroup && mContact!!.type == 2) {
            rlTitle.visibility = View.VISIBLE
        } else {
            rlTitle.visibility = View.GONE
        }

        if (DataProvider.getCustomGroup()) {
            ivEdit.visibility = View.VISIBLE
        } else {
            ivEdit.visibility = View.GONE
        }
    }


    private fun sendTextMsg(msg: String) {
        val chatMessage = ChatMessage()
        chatMessage.fuid = DataProvider.getHolderId()
        chatMessage.tuid = mContact?.friendId ?: ""
        chatMessage.type = if (mContact?.isGroup == true) 1 else 0
        chatMessage.msgType = ChatMsgProtos.ChatMsgType.TEXT_VALUE
        chatMessage.msgBody = msg
        chatMessage.msgTime = System.currentTimeMillis()
        chatMessage.state = ChatMsgProtos.ChatMsgState.STATE_SENDING_VALUE

        MessageDelegate.getManager()
            .handleOutgoingMessage(chatBinder, mContact, chatMessage, false)
    }


    private fun getMessages(): MutableList<ChatMessage?>? {
        return if (mContact?.isGroup == true) {
            DBUtils.loadGroupMessageByGroupId(mContact!!.friendId)
        } else {
            val messages = DBUtils.loadAllMessageByFriendId(mContact!!.friendId)
            if (BuildConfig.DEBUG) {
                messages?.forEach {
                    Logger.e(it.toString())
                }
            }
            return messages
        }
    }

    /**
     * 滑动到指定位置
     *
     * @param mRecyclerView
     * @param position
     */
    private fun smoothMoveToPosition(mRecyclerView: RecyclerView?, position: Int) {
        Logger.d("*******smooth move to position[$position]*******")
        // 第一个可见位置
        val firstItem = mRecyclerView!!.getChildLayoutPosition(mRecyclerView.getChildAt(0))
        // 最后一个可见位置
        val lastItem = mRecyclerView.getChildLayoutPosition(
            mRecyclerView.getChildAt(
                mRecyclerView.childCount - 1
            )
        )
        mRecyclerView.clearOnScrollListeners()
        mRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                if (newState == 0) {
                    mRecyclerView.clearOnScrollListeners()
                }
            }
        })
        if (position < firstItem) {
            mRecyclerView.smoothScrollToPosition(position)
        } else if (position <= lastItem) {
            val movePosition = position - firstItem
            if (movePosition >= 0 && movePosition < mRecyclerView.childCount) {
                val top = mRecyclerView.getChildAt(movePosition).top
                mRecyclerView.smoothScrollBy(0, top)
            }
        } else {
            mRecyclerView.smoothScrollToPosition(position)
        }
    }

    private fun isVisiblePosition(position: Int): Boolean {
        // 第一个可见位置
        val firstItem = rvMsg.getChildLayoutPosition(rvMsg.getChildAt(0))
        // 最后一个可见位置
        val lastItem = rvMsg.getChildLayoutPosition(rvMsg.getChildAt(rvMsg.childCount - 1))
        return position in firstItem..lastItem
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        Logger.d(TAG, "onActivityResult->requestCode:$requestCode->resultCode:$resultCode")
        if (requestCode == 2000 && resultCode == 2000) {
            val newName = data?.getStringExtra("newName")?:""
            if (!TextUtils.isEmpty(newName)) {
                mContact?.name = newName
                tvTitle.text = newName
            }
            return
        }

        if (resultCode == RESULT_OK) {
            if (requestCode == REQUEST_CODE_TAKE_PHOTO) {
                val resource = data!!.getParcelableExtra<Uri>(Constants.EXTRA_PICTURE_URI)
                if (resource != null) {
                    val path: String = Utility.getRealFilePath(this, resource)
                    sendPhotoMessage(path)
                }
            } else if (requestCode == REQUEST_CODE_EMOJI) {
                val code = data!!.getIntExtra("emoji_code", -1)
                if (code < 0) {
                    return
                }
                val msgType: Int = when {
                    code < 100 -> ChatMsgProtos.ChatMsgType.TEXT_STICKER_VALUE
                    code in 101..199 -> ChatMsgProtos.ChatMsgType.SMALL_EXPRESSION_VALUE
                    code > 200 -> ChatMsgProtos.ChatMsgType.SMALL_EXPRESSION_VALUE
                    else -> ChatMsgProtos.ChatMsgType.TEXT_VALUE
                }
                mHandler.post {
                    val chatMessage = ChatMessage()
                    chatMessage.fuid = DataProvider.getHolderId()
                    chatMessage.tuid = mContact!!.friendId
                    chatMessage.type = if (mContact?.isGroup == true) 1 else 0
                    chatMessage.msgType = msgType
                    chatMessage.msgTime = System.currentTimeMillis()
                    chatMessage.msgBody = code.toString()
                    chatMessage.state = ChatMsgProtos.ChatMsgState.STATE_SENDING_VALUE
                    MessageDelegate.getManager()
                        .handleOutgoingMessage(chatBinder, mContact, chatMessage, false)
                }
            } else if (requestCode == REQUEST_CODE_SHARE_PHOTO) {
                sharePicPaths =
                    data!!.getStringArrayListExtra(Constants.EXTRA_SHARE_PHOTO) as ArrayList<String>
                if (sharePicPaths != null) {
                    if (sharePicPaths?.size == 1) {
                        sendPhotoMessage(sharePicPaths?.get(0))
                    } else {
                        val firstPic = sharePicPaths?.get(0)
                        sendPhotoMessage(firstPic)
                        sharePicPaths?.remove(firstPic)
                        sendPhotos()
                    }
                }

            } else if (requestCode == REQUEST_CODE) {
                mAdapter?.datas!!.removeAll(mAdapter!!.getChatMsgSelectedList())
                mAdapter?.resetSelectedChatMsgs()
            } else if (requestCode == REQUEST_CODE_PHRASE) {
                val phrase = data!!.getStringExtra(EXTRA_PHRASE)
                phrase?.apply {
                    sendTextMsg(this)
                }

            }
        }
    }

    private fun sendPhotos() {
        if (sharePicPaths != null && sharePicPaths!!.isNotEmpty()) {
            val path = sharePicPaths?.get(0)
            sharePicPaths?.remove(path)
            mHandler.postDelayed({
                sendPhotoMessage(path)
                runOnUiThread {
                    sendPhotos()
                }
            }, 2000)
        }
    }

    private fun sendPhotoMessage(path: String?) {
        if (!TextUtils.isEmpty(path)) {
            mHandler.post {
                val chatMessage = ChatMessage()
                chatMessage.fuid = DataProvider.getHolderId()
                chatMessage.tuid = mContact!!.friendId
                chatMessage.type = if (mContact?.isGroup == true) 1 else 0
                chatMessage.msgType = ChatMsgProtos.ChatMsgType.PHOTO_VALUE
                chatMessage.msgTime = System.currentTimeMillis()
                chatMessage.filePath = path
                MessageDelegate.getManager()
                    .handleOutgoingMessage(chatBinder, mContact, chatMessage, false)
            }
        }
    }

    override fun onMessageSending(target: ChatMessage) {
        Logger.d("*******onMessageSending*******target=$target")
        if (!isFinishing) {
            mHandler.post {
                mAdapter?.setData(getMessages())
                mAdapter?.notifyItemInserted(mAdapter?.itemCount!!)
                smoothMoveToPosition(rvMsg, mAdapter?.itemCount!!)
            }
        }
    }

    @SuppressLint("WrongConstant", "NotifyDataSetChanged")
    override fun onSendMessage(target: ChatMessage, isResend: Boolean) {
        Logger.d("*******onSendMessage*******target=$target")
        if (!isFinishing) {
            mHandler.post {
                mAdapter?.setData(getMessages())
                if (isResend) {
                    mAdapter?.notifyDataSetChanged()
                    rvMsg.scrollToPosition(mAdapter?.itemCount!! - 1)  // 直接跳转到最后一个 item
                } else {
                    val position: Int = mAdapter?.getPositionByItem(target)!!
                    Logger.e("itemCount=${mAdapter?.itemCount},getPositionByItem position=$position")
                    mAdapter?.notifyItemChanged(position)
                }
            }
        }
    }

    override fun onGetMessage(target: ChatMessage, isUpdate: Boolean) {
        Logger.d("*******onGetMessage*******target=$target")
        if (!isFinishing) {
            mHandler.post {
                mAdapter?.setData(getMessages())
                if (isUpdate) {
                    val position: Int = mAdapter?.getPositionByItem(target)!!
                    Logger.e("itemCount=${mAdapter?.itemCount},getPositionByItem position=$position")
                    mAdapter?.notifyItemChanged(position)
                } else {
                    mAdapter?.notifyItemInserted(mAdapter?.itemCount!!)
                    //收到消息，直接滚动到最后
                    smoothMoveToPosition(rvMsg, mAdapter?.itemCount!!)
                }
            }
        }
    }

    private fun stopPlay() {
        Logger.d(TAG, "停止正在播放的语音")
        mAdapter?.stopPlay()
    }

    override fun onDestroy() {
        super.onDestroy()
        val intent = Intent()
        intent.action = ACTION_CLEAR_NOTIFY_CHAT
        intent.putExtra(ACTION_CLEAR_NOTIFY_CHAT, false)
        sendBroadcast(intent)
        mHandler.removeCallbacksAndMessages(null)
        if (isCallReceiverRegistered) {
            unregisterReceiver(mCallReceiver)
            isCallReceiverRegistered = false
        }
        if (mAdapter != null) {
            mAdapter?.release()
        }
        MessageDelegate.getManager().unRegisterMessageListener()
        EventBus.getDefault().unregister(this)
    }


    override fun onClick(v: View?) {
        when (v!!.id) {
            R.id.iv_reply -> {
                AlarmRecorderDialog(this, R.layout.dialog_ring_edit, mContact!!).apply {
                    show()
                    setListener(object : OnDialogActionListener {

                        override fun onVoice(filePath: String?, duration: Long) {
                            Logger.e(TAG, "onVoice: $filePath")
                            if (FileUtils.isFileExists(filePath) && duration < 1000) {
                                FileUtils.deleteFile(filePath)
                                UToast.showCustomToast(
                                    this@WatchMessageActivity,
                                    resources.getString(R.string.recording_short_tip),
                                    Toast.LENGTH_LONG
                                )
                                return
                            }
                            mHandler.post {
                                val length = FileUtils.getFileDuration(filePath)
                                Logger.e(TAG, "length: $length")
                                if (length <= 0) {
                                    return@post
                                }
                                Logger.e(TAG, "return")
                                val chatMessage = ChatMessage()
                                chatMessage.fuid = DataProvider.getHolderId()
                                chatMessage.tuid = mContact!!.friendId
                                chatMessage.type = if (mContact?.isGroup == true) 1 else 0
                                chatMessage.msgType = ChatMsgProtos.ChatMsgType.VOICE_VALUE
                                chatMessage.msgTime = System.currentTimeMillis()
                                chatMessage.filePath = filePath
                                chatMessage.length = length
                                MessageDelegate.getManager().handleOutgoingMessage(
                                    chatBinder, mContact, chatMessage, false
                                )
                            }
                        }

                        override fun onEmoji() {
                            val intent = Intent(
                                this@WatchMessageActivity,
                                EmoticonsActivity::class.java
                            )
                            intent.putExtra(Constants.EXTRA_CONTACT, mContact)
                            startActivityForResult(
                                intent,
                                REQUEST_CODE_EMOJI
                            )
                        }

                        override fun onPhoto() {
                            val takePhotoIntent =
                                Intent(this@WatchMessageActivity, TakePhotoActivity::class.java)
                            takePhotoIntent.putExtra(Constants.EXTRA_CONTACT, mContact)
                            startActivityForResult(
                                takePhotoIntent,
                                REQUEST_CODE_TAKE_PHOTO
                            )
                        }

                        override fun onPhrase() {
                            val takePhotoIntent =
                                Intent(this@WatchMessageActivity, PhraseActivity::class.java)
                            startActivityForResult(
                                takePhotoIntent,
                                REQUEST_CODE_PHRASE
                            )
                        }

                        override fun onQuitGroup() {
                            lifecycleScope.launch {
                                try {
                                    val groupId = mContact!!.friendId
                                    quitGroup(groupId)
                                } catch (e: Exception) {
                                    e.printStackTrace()
                                } finally {
                                    finish()
                                }
                            }
                        }
                    })
                }
            }

            R.id.iv_voice -> {
                ChatRecorderDialog(this).apply {
                    show()
                    setListener(object : ChatRecorderDialog.OnDialogActionListener {

                        override fun onVoice(filePath: String?, duration: Long) {
                            Logger.e(TAG, "onVoice: $filePath")
                            if (FileUtils.isFileExists(filePath) && duration < 1000) {
                                FileUtils.deleteFile(filePath)
                                UToast.showCustomToast(
                                    this@WatchMessageActivity,
                                    resources.getString(R.string.recording_short_tip),
                                    Toast.LENGTH_LONG
                                )
                                return
                            }
                            mHandler.post {
                                val length = FileUtils.getFileDuration(filePath)
                                Logger.e(TAG, "length: $length")
                                if (length <= 0) {
                                    return@post
                                }
                                Logger.e(TAG, "return")
                                val chatMessage = ChatMessage()
                                chatMessage.fuid = DataProvider.getHolderId()
                                chatMessage.tuid = mContact!!.friendId
                                chatMessage.type = if (mContact?.isGroup == true) 1 else 0
                                chatMessage.msgType = ChatMsgProtos.ChatMsgType.VOICE_VALUE
                                chatMessage.msgTime = System.currentTimeMillis()
                                chatMessage.filePath = filePath
                                chatMessage.length = length
                                MessageDelegate.getManager().handleOutgoingMessage(
                                    chatBinder, mContact, chatMessage, false
                                )
                            }
                        }
                    })
                }
            }
        }
    }

    @Throws(RemoteException::class)
    fun quitGroup(groupId: String) {
        PushApiClientProxy.fetchBinder().quitGroup(groupId)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onContactRefreshedEvent(event: ContactRefreshEvent) {
        Logger.e("onContactRefreshedEvent,${mContact}")
        //查询当前联系人是否存在，不存在则finish当前activity
        val contactInfo = mContact?.friendId?.let { DBUtils.getContactInfoByFriend(it) }
        Logger.e("contactInfo=${mContact}")
        if (contactInfo == null) {
            finish()
        }
    }

}